﻿// (c) Copyright 2013 Mike Riedel.
// This source is subject to the Microsoft Public License (Ms-PL).
// All other rights reserved.

using System.Collections.Generic;
using FreshMeat.Threading;

namespace FreshMeat.Storage
{
   /// <summary>
   /// Memory-based store; excellent performance but with no durability.
   /// </summary>
   /// <remarks>
   /// Despite this being a memory-based store, items are serialized and deserialized
   /// to provide the expected behaviors of a   First, callers expect that what's
   /// being put into the store is a "copy" of their item, so once it's in the store they
   /// are free to modify it without affecting the "copy" in the   Second, they 
   /// expect each retrieval of an item to return a new instance.  (And even if they
   /// don't consciously expect this, it's secretly what they want.)
   /// </remarks>
   /// <typeparam name="TId">Type of ID.</typeparam>
   /// <typeparam name="TData">Type of data.</typeparam>
   public class MemoryStore<TId, TData> : IStore<TId, TData>
   {
      readonly Dictionary<TId, string> cache = new Dictionary<TId, string>();
      readonly ISerializer<TData> serializer;
      readonly ILock resourceLock;

      /// <summary>
      /// Creates instance.
      /// </summary>
      /// <param name="serializer">Serializer to use.</param>
      public MemoryStore(ISerializer<TData> serializer)
      {
         this.serializer = serializer;
         resourceLock = new Lock();
      }

      /// <summary>
      /// Creates a context through which operations are performed against this store.
      /// Operations made through a context are isolated from operations made through other contexts.
      /// Contexts should be used and disposed as quickly as possible.
      /// </summary>
      /// <returns></returns>
      public IStoreContext<TId, TData> CreateContext()
      {
         resourceLock.Wait();
         return new MemoryStoreContext<TId, TData>(cache, serializer, resourceLock);
      }
   }
}